#pragma once

#include "Callbacks.h"
#include "TcpConnection.h"
#include <map>
#include <sys/epoll.h>
#include <string>

#define MAX_LINE 100
#define MAX_EVENTS 500
#define MAX_LISTENFD 5

class EventLoop;
class Socket;
class Channel;
class EventLoopThreadPool;

class TcpServer {
public:
    TcpServer(EventLoop* loop, int port);
    ~TcpServer();

    const std::string& name() const { return name_; }
    EventLoop* getLoop() const { return loop_; }

    void setConnectionCallback(const ConnectionCallback& cb) { connectionCallback_ = cb; }
    void setMessageCallback(const MessageCallback& cb) { messageCallback_ = cb; }

    void start();
    void setThreadNum(int numThreads);
    int nextID() { return nextConnId_; }

    void handleNewConnection();

private:
    void newConnection(int sockfd);
    void removeConnection(const TcpConnectionPtr& conn);
    void removeConnectionInLoop(const TcpConnectionPtr& conn);

    typedef std::map<std::string, TcpConnectionPtr> ConnectionMap;

    EventLoop* loop_;  // the acceptor loop

    std::shared_ptr<EventLoopThreadPool> threadPool_;
    
    // int listenfd_;
    std::shared_ptr<Socket> listenSocket_;
    std::shared_ptr<Channel> acceptor_;

    ConnectionCallback connectionCallback_;         // TcpConnection::connectEstablished调用
    MessageCallback messageCallback_;               // TcpConnection::handleRead调用
    WriteCompleteCallback writeCompleteCallback_;   // TcpConnection::handleWrite调用
    
    const std::string name_;
    bool started_;
    int nextConnId_;  // always in loop thread
    ConnectionMap connections_;

    int port_;
};